<?php

/**
 * This file is part of the Framework03 PHP framework.
 * @author Walter Tamboer
 * @package Framework03
 */

/**
 * This class represents a controller class that's given through HTTP.
 */
class FW_Controller_Request_Http extends FW_Controller_Request_Abstract
{
    /**
     * @var boolean Whether or not this controller request has been dispatched.
     */
    private $dispatched = false;

    /**
     * @var string The name of the default controller.
     */
    private $defaultControllerName = 'Index';

    /**
     * @var string The name of the requested controller.
     */
    private $controllerName;

    /**
     * @var string The name of the default action.
     */
    private $defaultActionName = 'index';

    /**
     * @var string The name of the requested action.
     */
    private $actionName;

    /**
     * @var array A list with arguments passed to this request.
     */
    private $arguments = array();
    
    /**
     * @var string The base url of this request.
     */
    private $baseUrl = null;

    /**
     * Sets whether or not this controller request has been dispatched.
     * @param boolean $value Whether or not the request has been dispatched.
     */
    public function setDispatched($value)
    {
        $this->dispatched = $value;
    }
    
    /**
     * Gets a value that indicates whether or not this request has been dispatched.
     * @return boolean Returns a boolean that indicates whether or not this request has been dispatched.
     */
    public function isDispatched()
    {
        return $this->dispatched;
    }
    
    /**
     * Sets the name of the default controller.
     * @param string $name The name of the default controller.
     * @return FW_Controller_Request_Http
     */
    public function setDefaultController($name)
    {
        $this->defaultControllerName = $name;
        return $this;
    }

    /**
     * Gets the name of the controller that we're requesting.
     * @return string Returns the name of the requested controller.
     */
    public function getControllerName()
    {
        if (empty($this->controllerName))
        {
            $pathArray = $this->getPathArray();

            if (count($pathArray) > 0)
                $this->controllerName = $pathArray[0];
            else
                $this->controllerName = $this->defaultControllerName;

            $this->setControllerName($this->controllerName);
        }

        return $this->controllerName;
    }

    /**
     * Sets the name of the controller that we're requesting.
     * @param string $name The name of the controller to set.
     * @return FW_Controller_Request_Abstract
     */
    public function setControllerName($name)
    {
        $this->controllerName = ucfirst($name . 'Controller');
        return $this;
    }

    /**
     * Gets the name of the action that we're requesting.
     * @return string Returns the name of the requested action.
     */
    public function getActionName()
    {
        if (empty($this->actionName))
        {
            $pathArray = $this->getPathArray();
            
            if (count($pathArray) > 1)
                $this->actionName = $pathArray[1];
            else
                $this->actionName = $this->defaultActionName;

			$this->actionName = $this->formatActionName($this->actionName);
            $this->actionName .= 'Action';
        }

        return $this->actionName;
    }

    /**
     * Sets the name of the action that we're requesting.
     * @param string $name The name of the action to set.
     * @return FW_Controller_Request_Abstract
     */
    public function setActionName($name)
    {
        $this->actionName = $this->formatActionName($name) . 'Action';
        return $this;
    }

    /**
     * Sets the arguments of the action that we're requesting.
     * @param array $arguments The arguments.
     * @return FW_Controller_Request_Abstract
     */
    public function setArguments(array $arguments)
    {
        $this->arguments = $arguments;
        return $this;
    }

    /**
     * Gets the arguments that we're passed to this request.
     * @return array
     */
    public function getArguments()
    {
        if (count($this->arguments) < 1)
        {
            $pathArray = $this->getPathArray();

            if (count($pathArray) >= 2)
            {
                array_shift($pathArray);
                array_shift($pathArray);
            }
            
            $this->arguments = $pathArray;
        }

        return $this->arguments;
    }

    /**
     * Gets the additional path info of this url.
     * @return string Returns the path info given in the url.
     */
    public function getPathInfo()
    {
        $pathInfo = isset($_SERVER[ 'PATH_INFO' ]) ? $_SERVER[ 'PATH_INFO' ] : '/';

        return trim(urldecode($pathInfo), '/');
    }

    /**
     * Gets the additional path info of this url splitted by the slash.
     * @return array Returns the path info given in the url.
     */
    public function getPathArray()
    {
        $pathInfo = $this->getPathInfo();

        return (empty($pathInfo) ? array() : explode('/', $pathInfo));
    }

    /**
     * Gets the base url of this request.
     * @return string
     */
    public function getBaseUrl()
    {
        if ($this->baseUrl == null)
        {
            $baseUrl = dirname($_SERVER['SCRIPT_NAME']);
            
            $this->baseUrl = rtrim($baseUrl, '/');
        }

        return $this->baseUrl;
    }

	/**
	 * Converts an actionname from 'hello-world' to 'helloWorld'
	 * @param string the actionName
	 * @return string the formatted actionName
	 */
	protected function formatActionName($name)
	{
		$splitted = preg_split('#-(?=[a-z])#', $name);
		$name = array_shift($splitted);
		foreach ($splitted as $word)
			$name .= ucfirst($word);

        return $name;
	}
	
	/**
	 * Checks if the current request is a POST request.
	 * @return bool Returns true if this is a POST request; false otherwise.
	 */
	public function isPost()
	{
		return strtolower($_SERVER[ 'REQUEST_METHOD' ]) == 'post';
	}
	
	/**
	 * Checks if the current request is a GET request.
	 * @return bool Returns true if this is a GET request; false otherwise.
	 */
	public function isGet()
	{
		return strtolower($_SERVER[ 'REQUEST_METHOD' ]) == 'get';
	}
}
